package com.syf.controller;


import com.syf.geetest.GeetestLib;
import com.syf.geetest.GeetestLibResult;
import com.syf.model.R;
import com.syf.util.IpUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 1.极验验证码 控制层：
 *      1)获取极验的第一次数据包:
 *          GeetestLibResult result = geetestLib.register(digestmod, paramMap); // 与极验服务器交互
 *      2)极验证的二次数据校验:
 *          result = geetestLib.successValidate(challenge, validate, seccode, paramMap);
 *
 * 2.返回结果信息GeetestLibResult:
 *      1)status 成功失败的标识码，1表示成功，0表示失败
 *      2)data   返回数据，json格式
 *      3)msg    备注信息，如异常信息等
 *
 * 3.校验流程：
 *      1)封装数据
 *      2)与服务器交互
 *      3)将status服务器服务状态、user极验证里面的user 缓存到 redis中
 *      4)返回交互验证的数据包
 */
@RestController
@RequestMapping("/gt")
public class GeetestController {

    @Autowired
    private GeetestLib geetestLib;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @GetMapping("/register")
    @ApiOperation(value = "获取极验的第一次数据包(用户验证前)---")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uuid" ,value = "用户验证的一个凭证")
    })
    public R<String> register(String uuid) {
//        GeetestLib gtLib = new GeetestLib(GeetestConfig.GEETEST_ID, GeetestConfig.GEETEST_KEY);   //已初始化了
        String digestmod = "md5";
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("digestmod", digestmod); //1.加密算法
        paramMap.put("user_id", uuid); //2.客户端用户的唯一标识(前端发送一个UUID)
        paramMap.put("client_type", "web"); //3.客户端类型，web：电脑上的浏览器；h5：手机上的浏览器，包括移动应用内完全内置的web_view；native：通过原生sdk植入app应用的方式；unknown：未知
        //上下文对象 获取 request对象 -> IpUtil.getIpAddr(util工具类) -> ip地址
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        paramMap.put("ip_address", IpUtil.getIpAddr(servletRequestAttributes.getRequest())); //4.客户端请求sdk服务器的ip地址

        // 【与极验服务器交互】
        GeetestLibResult result = geetestLib.register(digestmod, paramMap);

        // 将结果状态写到session中，此处register接口存入session，后续validate接口会取出使用
        // 注意，此demo应用的session是单机模式，格外注意分布式环境下session的应用
        // request.getSession().setAttribute( result.getStatus());
        // request.getSession().setAttribute("userId", userId);

        //此处用redis存储，并设置过期时间(极验验证API服务状态Session Key、极验证里面的user)
        redisTemplate.opsForValue().set(GeetestLib.GEETEST_SERVER_STATUS_SESSION_KEY, result.getStatus(), 180, TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(GeetestLib.GEETEST_SERVER_USER_KEY + ":" + uuid, uuid, 180, TimeUnit.SECONDS);

        // 注意，不要更改返回的结构和值类型 String【result对象: GeetestLibResult(status,data,msg)】
        return R.ok(result.getData());
    }

}
